package com.hengmei.smallscreen.utils

import android.util.Log
import com.example.x6.serial.Uart.byteMerger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
import tp.xmaihh.serialport.SerialHelper
import tp.xmaihh.serialport.bean.ComBean
import tp.xmaihh.serialport.stick.StaticLenStickPackageHelper
import tp.xmaihh.serialport.stick.VariableLenStickPackageHelper
import java.io.IOException
import java.io.UnsupportedEncodingException
import java.nio.ByteOrder
import kotlin.coroutines.CoroutineContext


sealed class SerialAction {
    data class ContrastQrCode(val bytes: ByteArray) : SerialAction() {
        override fun equals(other: Any?): Boolean {
            if (this === other) return true
            if (other !is ContrastQrCode) return false

            return bytes.contentEquals(other.bytes)
        }

        override fun hashCode(): Int {
            return bytes.contentHashCode()
        }
    }
}

class SerialUtils  private constructor(): CoroutineScope {
    private var serialHelper: SerialHelper? = null
    private var strSerialHelper: SerialHelper? = null
    private var sensorHelper: SerialHelper? = null
    var channelAction = Channel<SerialAction>(Channel.UNLIMITED)

    private var job: Job = Job()

    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job

    ///开启检测设备串口
    fun initSerialMCU() {


        serialHelper = object : SerialHelper("dev/ttyS2", 115200) {
            override fun onDataReceived(comBean: ComBean) {

                launch{
                channelAction.send(SerialAction.ContrastQrCode(comBean.bRec))
                    SerialAction.ContrastQrCode(
                        comBean.bRec
                    )
                }
            }
        }
        //        sensorHelper.setStickPackageHelper(new VariableLenStickPackageHelper(ByteOrder.LITTLE_ENDIAN,1,2,0));
//        serialHelper?.stickPackageHelper = StaticLenStickPackageHelper(25)
        Log.d("开启串口", serialHelper?.isOpen().toString() + "")
        if (!serialHelper?.isOpen!!) {
            try {
                serialHelper?.open()
            } catch (e: IOException) {
                e.printStackTrace()
            }catch (e2: SecurityException) {
                e2.printStackTrace()
            }

        }

    }

    ///开启打印机串口
    fun initSerialStr() {
        strSerialHelper = object : SerialHelper("dev/ttyS4", 9600) {
            override fun onDataReceived(comBean: ComBean) {}
        }
        if (!strSerialHelper?.isOpen!!) {
            try {
                strSerialHelper?.open()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }

    ///开启传感器串口
    fun initSensor(getSensonListener: getSensonListener): SerialHelper {
        sensorHelper = object : SerialHelper("dev/ttyS7", 4800) {
            override fun onDataReceived(comBean: ComBean) {
                getSensonListener.Sensorresult(comBean)
            }
        }
        sensorHelper?.setStickPackageHelper(
            VariableLenStickPackageHelper(
                ByteOrder.LITTLE_ENDIAN,
                1,
                2,
                5
            )
        )
        if (!sensorHelper?.isOpen()!!) {
            try {
                sensorHelper?.open()
                Log.d("开启串口sensor", sensorHelper?.isOpen().toString() + "")
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        return sensorHelper!!
    }

    fun sensorSend(bytes: ByteArray?) {
        if (sensorHelper != null) {
            try {
                sensorHelper!!.send(bytes)
            } catch (e: Exception) {
            }
        }
    }

    fun closeSensor() {
        sensorHelper!!.close()
    }

    fun sendMCU(bytes: ByteArray?) {
        if (serialHelper!=null) {
            serialHelper!!.send(bytes)
        }
    }

    fun closeStr() {
        strSerialHelper!!.close()
    }

    fun sendText(str: String) {
        try {
            val bs = str.toByteArray(charset("GB2312"))
            strSerialHelper!!.send(bs)
        } catch (e: UnsupportedEncodingException) {
            e.printStackTrace()
        }
    }

    fun sendCode(str: String) {
        try {
            val A = str.toByteArray(charset("GB2312"))
            val B = byteArrayOf(0x1D, 0x4D, 0x01) // 读取通道值
            val D = byteArrayOf(0x00) // 读取通道值
            val C = byteMerger(B, A)
            val E = byteMerger(C, D)
            strSerialHelper!!.send(E)
        } catch (e: UnsupportedEncodingException) {
            e.printStackTrace()
        }
    }

    interface getResultListener {
        fun DataReciver(comBean: ComBean?)
    }

    interface getSensonListener {
        fun Sensorresult(comBean: ComBean?)
    }

    companion object {
        @Volatile
        var instance: SerialUtils? = null
            get() {
                if (field == null) {
                    synchronized(SerialUtils::class.java) {
                        if (field == null) {
                            field = SerialUtils()
                        }
                    }
                }
                return field
            }
            private set

        //System.arraycopy()方法
        fun byteMerger(bt1: ByteArray, bt2: ByteArray): ByteArray {
            val bt3 = ByteArray(bt1.size + bt2.size)
            System.arraycopy(bt1, 0, bt3, 0, bt1.size)
            System.arraycopy(bt2, 0, bt3, bt1.size, bt2.size)
            return bt3
        }
    }

}